package com.mjlf.mjatis.config;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mjlf.mjatis.alias.Alias;
import com.mjlf.mjatis.alias.AliasParser;
import com.mjlf.mjatis.datasource.DataSourceParser;
import com.mjlf.mjatis.datasource.DataSourceStatement;
import com.mjlf.mjatis.exception.AliasException;
import com.mjlf.mjatis.exception.DataSourceException;
import com.mjlf.mjatis.excutor.Executor;
import com.mjlf.mjatis.mapper.MapperParser;
import com.mjlf.mjatis.mapper.MapperStatement;
import com.mjlf.mjatis.plugin.MapperPlugin;
import com.mjlf.mjatis.result.ResultMap;
import lombok.Data;
import lombok.extern.java.Log;

import javax.sql.DataSource;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName Configuration
 * @Author mjlft
 * @Date 2020/5/26 23:00
 * @Version 1.0
 * @Description TODO
 */
@Data
@Log
public class Configuration implements Serializable {

    private DataSource dataSource;

    //dataSource元数据存储类
    private Set<Alias> aliases;
    private Map<String,MapperStatement> mapperStatements = new ConcurrentHashMap<>();
    private Set<MapperPlugin> mapperPlugins;
    private Set<ResultMap> resultMaps;

    private AliasParser aliasParser = new AliasParser();
    private DataSourceParser dataSourceParser = new DataSourceParser();
    private MapperParser mapperParser = new MapperParser();

    private Executor executor = null;

    private Map<Class, Object> cacheMappers = Collections.EMPTY_MAP;

    public static enum ConfEnum {
        DATA_SOURCE,
        ALIAS,
        PLUGIN,
        MAPPER,
        ENVIRONMENT
    }

    /**
     * 统一解析配置，这里主要解析Json对象，根据ConfEnum进行不同的规则解析
     * @param configJson
     * @param configArray
     * @param confEnum
     */
    public void parseConfigJson(JSONObject configJson, JSONArray configArray, ConfEnum confEnum){
        switch (confEnum){
            case DATA_SOURCE:
                dataSourceParser.parseConfig(configJson, this);
                break;
            case ALIAS:
                aliasParser.parseConfig(configArray, this);
                break;
            case MAPPER:
                mapperParser.parseConfig(configArray, this);
                break;
            case PLUGIN:
                break;
            case ENVIRONMENT:
                break;
        }
    }

    /**
     * 解析DataSource
     */
    public void parseDataSource(JSONObject jsonObject){

    }

    /**
     * 解析入口， 再SqlSessionFactory中需要调用Configuration的解析
     */
    public void parse(JSONObject configJson){
        //带修改，
        //拿取dataSource配置信息
        if(!configJson.containsKey("dataSource")){
            log.info("配置文件错误，找不到dataSource配置信息， 请配置dataSource项");
            throw new DataSourceException("配置文件错误，找不到dataSource配置信息， 请配置dataSource项");
        }
        JSONObject dataSourceJson = configJson.getJSONObject("dataSource");
        parseConfigJson(dataSourceJson, null, ConfEnum.DATA_SOURCE);

        //解析别名
        if(!configJson.containsKey("alias")){
            log.info("配置文件错误，找不到alias配置信息， 请配置alias项");
        }else {
            JSONArray aliasArray = configJson.getJSONArray("alias");
            parseConfigJson(null, aliasArray, ConfEnum.ALIAS);
        }

        //解析Mapper
        if(!configJson.containsKey("mapper")){
            log.info("配置文件错误，找不到mapper配置信息， 请配置mapper项");
            throw new DataSourceException("配置文件错误，找不到mapper配置信息， 请配置mapper项");
        }
        JSONArray mapperArray = configJson.getJSONArray("mapper");
        parseConfigJson(null, mapperArray, ConfEnum.MAPPER);
    }

    public void parse(String basePackagePath){

    }

    public void parse(JSONObject configJson, String basePackagePath){
        parse(configJson);
        parse(basePackagePath);
    }
}
